}
if ((c = tb[LEASE_CFG_ATTR_NAME])) {
+ if (!odhcpd_hostname_valid(blobmsg_get_string(c)))
+ goto err;
+
lease_cfg->hostname = strdup(blobmsg_get_string(c));
- if (!lease_cfg->hostname || !odhcpd_valid_hostname(lease_cfg->hostname))
+ if (!lease_cfg->hostname)
goto err;
}
static void lease_cfg_update_leases(struct lease_cfg *lease_cfg)
{
- struct dhcpv4_lease *a4 = lease_cfg->dhcpv4_lease;
+ struct dhcpv4_lease *lease4 = lease_cfg->dhcpv4_lease;
struct dhcpv6_lease *lease6;
- if (a4) {
- free(a4->hostname);
- a4->hostname = NULL;
+ if (lease4) {
+ free(lease4->hostname);
+ lease4->hostname = NULL;
- if (lease_cfg->hostname)
- a4->hostname = strdup(lease_cfg->hostname);
+ if (lease_cfg->hostname) {
+ lease4->hostname = strdup(lease_cfg->hostname);
+ lease4->hostname_valid = true;
+ }
}
list_for_each_entry(lease6, &lease_cfg->dhcpv6_leases, lease_cfg_list) {
free(lease6->hostname);
lease6->hostname = NULL;
- if (lease_cfg->hostname)
+ if (lease_cfg->hostname) {
lease6->hostname = strdup(lease_cfg->hostname);
+ lease6->hostname_valid = true;
+ }
lease6->leasetime = lease_cfg->leasetime;
}
if (lease_cfg) {
lease->flags |= OAF_STATIC;
- if (lease_cfg->hostname)
+ if (lease_cfg->hostname) {
lease->hostname = strdup(lease_cfg->hostname);
+ lease->hostname_valid = true;
+ }
lease_cfg->dhcpv4_lease = lease;
lease->lease_cfg = lease_cfg;
lease->hostname = new_name;
memcpy(lease->hostname, req_hostname, req_hostname_len);
lease->hostname[req_hostname_len] = 0;
-
- if (odhcpd_valid_hostname(lease->hostname))
- lease->flags &= ~OAF_BROKEN_HOSTNAME;
- else
- lease->flags |= OAF_BROKEN_HOSTNAME;
+ lease->hostname_valid = odhcpd_hostname_valid(lease->hostname);
}
}
if (lease_cfg && assigned) {
a->flags |= OAF_STATIC;
- if (lease_cfg->hostname)
+ if (lease_cfg->hostname) {
a->hostname = strdup(lease_cfg->hostname);
+ a->hostname_valid = true;
+ }
if (lease_cfg->leasetime)
a->leasetime = lease_cfg->leasetime;
a->hostname = tmp;
memcpy(a->hostname, hostname, hostname_len);
a->hostname[hostname_len] = 0;
-
- if (odhcpd_valid_hostname(a->hostname))
- a->flags &= ~OAF_BROKEN_HOSTNAME;
- else
- a->flags |= OAF_BROKEN_HOSTNAME;
+ a->hostname_valid = odhcpd_hostname_valid(a->hostname);
}
}
a->accept_fr_nonce = accept_reconf;
return 0;
}
-bool odhcpd_valid_hostname(const char *name)
+bool odhcpd_hostname_valid(const char *name)
{
-#define MAX_LABEL 63
const char *c, *label, *label_end;
int label_sz = 0;
for (c = name, label_sz = 0, label = name, label_end = name + strcspn(name, ".") - 1;
- *c && label_sz <= MAX_LABEL; c++) {
+ *c && label_sz <= DNS_MAX_LABEL_LEN; c++) {
if ((*c >= '0' && *c <= '9') ||
(*c >= 'A' && *c <= 'Z') ||
(*c >= 'a' && *c <= 'z')) {
continue;
}
+ /* FIXME: underscore is not allowed in RFC 1035, RFC 1123? */
if ((*c == '_' || *c == '-') && c != label && c != label_end) {
label_sz++;
continue;
return false;
}
- return (label_sz && label_sz <= MAX_LABEL ? true : false);
+ return (label_sz && label_sz <= DNS_MAX_LABEL_LEN ? true : false);
}
OAF_TENTATIVE = (1 << 0),
OAF_BOUND = (1 << 1),
OAF_STATIC = (1 << 2),
- OAF_BROKEN_HOSTNAME = (1 << 3),
- OAF_DHCPV6_NA = (1 << 4),
- OAF_DHCPV6_PD = (1 << 5),
+ OAF_DHCPV6_NA = (1 << 3),
+ OAF_DHCPV6_PD = (1 << 4),
};
/* 2-byte type + 128-byte DUID, RFC8415, §11.1 */
unsigned int flags; // OAF_*
time_t valid_until; // CLOCK_MONOTONIC time, 0 = inf
char *hostname; // client hostname
+ bool hostname_valid; // is the hostname one or more valid DNS labels?
size_t hwaddr_len; // hwaddr length
uint8_t hwaddr[ETH_ALEN]; // hwaddr (only MAC supported)
unsigned int flags;
uint32_t leasetime;
char *hostname;
+ bool hostname_valid; // is the hostname one or more valid DNS labels?
uint32_t iaid;
uint16_t duid_len;
void odhcpd_enum_addr6(struct interface *iface, struct dhcpv6_lease *lease,
time_t now, odhcpd_enum_addr6_cb_t func, void *arg);
int odhcpd_parse_addr6_prefix(const char *str, struct in6_addr *addr, uint8_t *prefix);
-bool odhcpd_valid_hostname(const char *name);
+bool odhcpd_hostname_valid(const char *name);
int config_parse_interface(void *data, size_t len, const char *iname, bool overwrite);
struct lease_cfg *config_find_lease_cfg_by_duid_and_iaid(const uint8_t *duid,
{
char ipbuf[INET6_ADDRSTRLEN];
- if (!lease->hostname || lease->flags & OAF_BROKEN_HOSTNAME || !(lease->flags & OAF_DHCPV6_NA))
+ if (!lease->hostname || !lease->hostname_valid || !(lease->flags & OAF_DHCPV6_NA))
return false;
if (ctxt->fp) {
{
char ipbuf[INET_ADDRSTRLEN];
- if (!lease->hostname || lease->flags & OAF_BROKEN_HOSTNAME)
+ if (!lease->hostname || !lease->hostname_valid)
return false;
if (ctxt->fp) {
struct write_ctxt *ctxt = (struct write_ctxt *)arg;
char ipbuf[INET6_ADDRSTRLEN];
- if (lease->hostname && !(lease->flags & OAF_BROKEN_HOSTNAME) && lease->flags & OAF_DHCPV6_NA) {
+ if (lease->hostname && lease->hostname_valid && lease->flags & OAF_DHCPV6_NA) {
md5_hash(addr, sizeof(*addr), &ctxt->md5);
md5_hash(lease->hostname, strlen(lease->hostname), &ctxt->md5);
}
fprintf(ctxt->fp,
"# %s %s %x %s%s %" PRId64 " %" PRIx64 " %" PRIu8,
ctxt->iface->ifname, duidbuf, ntohl(lease->iaid),
- (lease->flags & OAF_BROKEN_HOSTNAME) ? "broken\\x20" : "",
- (lease->hostname ? lease->hostname : "-"),
+ lease->hostname_valid ? "" : "broken\\x20",
+ lease->hostname ? lease->hostname : "-",
(lease->valid_until > ctxt->now ?
(int64_t)(lease->valid_until - ctxt->now + ctxt->wall_time) :
(INFINITE_VALID(lease->valid_until) ? -1 : 0)),
char hexhwaddr[sizeof(lease->hwaddr) * 2 + 1];
char ipbuf[INET6_ADDRSTRLEN];
- if (lease->hostname && !(lease->flags & OAF_BROKEN_HOSTNAME)) {
+ if (lease->hostname && lease->hostname_valid) {
md5_hash(&lease->ipv4, sizeof(lease->ipv4), &ctxt->md5);
md5_hash(lease->hostname, strlen(lease->hostname), &ctxt->md5);
}
fprintf(ctxt->fp,
"# %s %s ipv4 %s%s %" PRId64 " %x 32 %s/32\n",
ctxt->iface->ifname, hexhwaddr,
- (lease->flags & OAF_BROKEN_HOSTNAME) ? "broken\\x20" : "",
- (lease->hostname ? lease->hostname : "-"),
+ lease->hostname_valid ? "" : "broken\\x20",
+ lease->hostname ? lease->hostname : "-",
(lease->valid_until > ctxt->now ?
(int64_t)(lease->valid_until - ctxt->now + ctxt->wall_time) :
(INFINITE_VALID(lease->valid_until) ? -1 : 0)),
if (c->flags & OAF_STATIC)
blobmsg_add_string(&b, NULL, "static");
- if (c->flags & OAF_BROKEN_HOSTNAME)
+ if (!c->hostname_valid)
blobmsg_add_string(&b, NULL, "broken-hostname");
blobmsg_close_array(&b, m);